package com.bocloud.cmp.driver.config;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.model.Butler;
import com.bocloud.common.model.BaseResult;
import com.bocloud.common.utils.JSONTools;

/**
 * 
 * 云平台配置信息缓存通用类
 * 
 * @author dmw
 *
 */
public class Configuration {

	private static Logger logger = LoggerFactory.getLogger(Configuration.class);
	private Map<String, Butler> butlerMap;
	static ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
	static Lock readLock = rwLock.readLock();
	static Lock writeLock = rwLock.writeLock();

	/**
	 * 
	 */
	private Configuration() {
		super();
		butlerMap = new ConcurrentHashMap<>();
	}

	/**
	 * 获取配置实例方法，即将被废弃
	 * 
	 * @return
	 */
	public static Configuration instance() {
		return ConfigurationContainer.instance;
	}

	/**
	 * 获取配置实例标准方法
	 * 
	 * @return
	 */
	public static Configuration getInstance() {
		return ConfigurationContainer.instance;
	}

	/**
	 * 更新整体配置
	 * 
	 * @param data
	 */
	public void update(String data) {
		writeLock.lock();
		try {
			if (StringUtils.isEmpty(data)) {
				return;
			}
			processNull();
			BaseResult<JSONObject> result = JSONTools.isJSON(data);
			if (result.isFailed()) {
				logger.error("Update config error: 传入参数格式化错误！");
				return;
			}
			JSONObject jsonObject = result.getData();
			Set<String> butlerKeys = jsonObject.keySet();
			BaseResult<Butler> parseResult = null;
			for (String butlerKey : butlerKeys) {
				parseResult = parseButler(jsonObject.getString(butlerKey));
				if (parseResult.isFailed()) {
					continue;
				}
				butlerMap.put(butlerKey, parseResult.getData());
			}
		} catch (Exception e) {
			logger.error("update config error:", e);
		} finally {
			writeLock.unlock();
		}
	}

	/**
	 * 获取云平台配置
	 * 
	 * @param key
	 * @return
	 */
	public Butler getConfig(String key) {
		readLock.lock();
		try {
			processNull();
			return butlerMap.get(key);
		} catch (Exception e) {
			logger.error("get config error:", e);
			return null;
		} finally {
			readLock.unlock();
		}
	}

	/**
	 * 更新指定key的云平台
	 * 
	 * @param key
	 * @param butler
	 */
	public void update(String key, Butler butler) {
		processNull();
		if (StringUtils.isEmpty(key) || null == butler) {
			return;
		}
		writeLock.lock();
		try {
			butlerMap.put(key, butler);
		} catch (Exception e) {
			logger.error("update key【{}】 butler exception ", key, e);
		} finally {
			writeLock.unlock();
		}
	}

	private void processNull() {
		if (null == butlerMap) {
			butlerMap = new ConcurrentHashMap<>();
		}
	}

	private BaseResult<Butler> parseButler(String butlerInfo) {
		try {
			Butler butler = JSONObject.parseObject(butlerInfo, Butler.class);
			return new BaseResult<Butler>(true, "success", butler);
		} catch (Exception e) {
			logger.error("parseButler exception:", e);
			return new BaseResult<>(false, e.getMessage());
		}
	}

	private static class ConfigurationContainer {
		private static Configuration instance = new Configuration();
	}
}
